extends CharacterBody2D
# 测试用哥布林：
# - 通过 NavigationAgent2D 寻路到 "Castle1" 建筑
# - 若当前导航层与目标层不同，使用 NavigationLink2D 进行跨层路由
# - 动画与速度基于下一寻路点计算
# - 每 1 秒打印一次 NavAgent 目标终点与自身速度

@export var move_speed: float = 140.0

@onready var anim: AnimatedSprite2D = get_node_or_null("AnimatedSprite2D")
@onready var agent: NavigationAgent2D = get_node_or_null("NavigationAgent2D")

var _castle: Node2D
var _route_stage: int = 0
var _current_link: NavigationLink2D = null
var _links: Array[NavigationLink2D] = []
var _debug_elapsed: float = 0.0
var get_to_target = false 

func _ready() -> void:
	# 初始化目标城堡与可用导航链接集合
	_castle = _find_castle()
	_links = _collect_links()
	if anim:
		anim.play("idle")

func _physics_process(delta: float) -> void:
	# 缺少导航代理时不做任何寻路
	if agent == null:
		return
	# 目标不存在或未有效时，停止并播放待机
	if _castle == null or not is_instance_valid(_castle):
		velocity = Vector2.ZERO
		if anim:
			anim.play("idle")
		move_and_slide()
		return
	# 导航地图未准备好时，直接设置终点为城堡位置
	var map := agent.get_navigation_map()
	if not map.is_valid() or NavigationServer2D.map_get_iteration_id(map) == 0:
		agent.target_position = _castle.global_position
	else:
		# 根据当前位置与目标位置的导航层决定是否需要跨层路由
		var cur_layer := _get_layer_at(global_position)
		var tar_layer := _get_layer_at(_castle.global_position)
		if cur_layer == tar_layer or tar_layer == 0 or cur_layer == 0:
			agent.navigation_layers = tar_layer if tar_layer != 0 else agent.navigation_layers
			agent.target_position = _castle.global_position
			_route_stage = 0
			_current_link = null
		else:
			if _route_stage == 0:
				# 选择一条最优的链接作为跨层入口
				_current_link = _pick_link(cur_layer, tar_layer)
				if _current_link:
					var other := _other_layer(_current_link.navigation_layers, cur_layer)
					agent.navigation_layers = cur_layer | other
					agent.target_position = _current_link.start_position
					_route_stage = 1
				else:
					agent.target_position = _castle.global_position
			elif _route_stage == 1:
				# 到达链接起点后，切换到链接层并以终点为导航目标
				if global_position.distance_to(_current_link.start_position) <= 8.0 or agent.is_navigation_finished():
					agent.target_position = _current_link.end_position
					agent.navigation_layers = _current_link.navigation_layers
					_route_stage = 2
			elif _route_stage == 2:
				# 通过链接后，切换至另一侧层级并回到城堡寻路
				if global_position.distance_to(_current_link.end_position) <= 8.0 or agent.is_navigation_finished():
					var other2 := _other_layer(_current_link.navigation_layers, cur_layer)
					agent.navigation_layers = other2
					agent.target_position = _castle.global_position
					_route_stage = 0
					_current_link = null
	if agent.is_navigation_finished():
		# 路径完成：停止并播放待机
		velocity = Vector2.ZERO
		if get_to_target== false:
			print("角色已抵达目标点")
			get_to_target = true
		
		if anim:
			anim.play("idle")	
	else:
		# 路径未完成：指向下一点的方向移动
		var next_point: Vector2 = agent.get_next_path_position()
		velocity = (next_point - global_position).normalized() * move_speed
		if anim:
			if velocity.x > 0.0:
				anim.flip_h = false
			elif velocity.x < 0.0:
				anim.flip_h = true
			anim.play("run_right")
	move_and_slide()

	# 每秒打印一次 NavAgent 目标终点与自身速度（x、y）
	_debug_elapsed += delta
	if _debug_elapsed >= 1.0:
		var tar: Vector2 = agent.target_position if agent else Vector2.ZERO
		print("Nav目标终点=(%f, %f) 速度=(%f, %f)" % [tar.x, tar.y, velocity.x, velocity.y])
		_debug_elapsed = 0.0

func _find_castle() -> Node2D:
	# 在组 "building" 中查找名为 "Castle1" 的节点
	var nodes: Array[Node] = get_tree().get_nodes_in_group("building")
	for n in nodes:
		if n is Node2D and String(n.name) == "Castle1":
			return n as Node2D
	return null

func _get_layer_at(pos: Vector2) -> int:
	# 查询某个位置对应导航区域的层掩码（bitmask）
	var map := agent.get_navigation_map()
	var rid := NavigationServer2D.map_get_closest_point_owner(map, pos)
	if rid.is_valid():
		return NavigationServer2D.region_get_navigation_layers(rid)
	return 0

func _other_layer(layers: int, current: int) -> int:
	# 在链接的层集合中，寻找非 current 的另一层位
	var bits := [1, 2, 4, 8, 16, 32, 64, 128]
	for b in bits:
		if (layers & b) != 0 and b != current:
			return b
	return current

func _collect_links() -> Array[NavigationLink2D]:
	# 收集整棵场景树中的 NavigationLink2D
	var out: Array[NavigationLink2D] = []
	var root := get_tree().current_scene
	if root:
		_collect_links_rec(root, out)
	return out

func _collect_links_rec(n: Node, out: Array[NavigationLink2D]) -> void:
	# 递归遍历并收集合格的链接节点
	if n is NavigationLink2D:
		out.append(n)
	for c in n.get_children():
		_collect_links_rec(c, out)

func _pick_link(cur_layer: int, tar_layer: int) -> NavigationLink2D:
	# 选择距离目标最近的合适链接作为跨层路径
	var best: NavigationLink2D = null
	var best_dist: float = INF
	for l: NavigationLink2D in _links:
		if (l.navigation_layers & cur_layer) != 0 and ((l.navigation_layers & tar_layer) != 0 or (l.navigation_layers & _other_layer(l.navigation_layers, cur_layer)) != 0):
			var d: float = l.end_position.distance_to(_castle.global_position)
			if d < best_dist:
				best_dist = d
				best = l
	return best
